package ihm.panel.camera;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;

import ihm.applet.KrakenApplet;
import ihm.panel.PanelInterface;
import ihm.panel.TablePanel;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;

import network.KrakenClient;
import network.messages.KrakenClientMsg;
import network.messages.KrakenServerMsg;
import network.ssl.KrakenSSLClient;
import network.thread.NetworkThread;

import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

import tools.AppletConstant;
import tools.ConfParser;
import tools.FileUtils;
import tools.StringUtils;

import bdd.sql.server.bean.Camera;
import bdd.sql.server.bean.ServerAuth;
import bdd.sql.server.bean.ServerCentral;
import bdd.sql.server.bean.ServerWeb;
import bdd.sql.server.bean.User;
import bdd.sql.server.bean.Video;
import bdd.sql.server.hibernate.HibernateUtil;

/**
 * Panneau qui affiche les vidéos liées à une caméra.
 * @author Guillaume Pocas & Jean-Fraçois Augé
 */
public class VideoHistPanel extends TablePanel implements ActionListener, PanelInterface {

	// generic
	private static final long serialVersionUID = 1L;
	private KrakenApplet applet;
	private Camera camera;
	
	// table
	private DefaultTableModel video_atm;
	private JTable video_jt;
	private TableRowSorter<DefaultTableModel> sorter;
	//private boolean filtering = false;
	//private static final int MAX_RESULT = 1000;

	private static String[] COLUMN_NAMES = {"ID", "Camera", "Heure", "Jour", "Mois", "Année", "Poids"};
	private Object[][] column_content;

	// ihm
	private CameraPanel camera_jp;

	private JPanel bottom_jp;
	private JButton read_jb;
	/*private JButton filter_jb;

	private JTextField hour_filter;
	private JTextField hour_end_filter;
	private JTextField day_filter;
	private JTextField month_filter;
	private JTextField year_filter;*/

	// network
	private String ip_central = "";
	private String ip_auth = "";
	private String ip_storage = "";
	private String ip_web = "";
	private String ip_cam = "";

	private int REQUEST_TYPE_KEY = 2;

	private KrakenSSLClient cmd_client;

	private Thread cmd_thread;

	/**
	 * Constructeur.
	 * @param app
	 * @param cam_jp
	 */
	public VideoHistPanel(KrakenApplet app, CameraPanel cam_jp) {
		this.applet = app;
		this.camera_jp = cam_jp;
		this.initPanel();
	}

	@Override
	public void initPanel() {
		/*
		 * Table part!
		 */
		setLayout(new BorderLayout());
		video_atm = new DefaultTableModel(populateModel(), COLUMN_NAMES);

		sorter = new TableRowSorter<DefaultTableModel>(video_atm);
		
		video_jt = new JTable(video_atm) {
			private static final long serialVersionUID = 1L;

			//  Returning the Class of each column will allow different
			//  renderers to be used based on Class
			@SuppressWarnings({ "unchecked", "rawtypes" })
			public Class getColumnClass(int column) {
				return getValueAt(0, column).getClass();
			}

			//  Les quatre premières colonnes ne sont pas modifiables
			public boolean isCellEditable(int row, int column) {
				int modelColumn = convertColumnIndexToModel(column);
				return (modelColumn == 0 || modelColumn == 1
						|| modelColumn == 2 || modelColumn == 3
						|| modelColumn == 4) ? false : true;
			}
		};
		video_jt.setPreferredScrollableViewportSize(video_jt.getPreferredSize());
		video_jt.setFillsViewportHeight(true);
		JScrollPane scrollPane = new JScrollPane(video_jt);
		add(scrollPane, BorderLayout.CENTER);
		
		video_jt.setRowSorter(sorter);


		/*
		 * Buttons part!
		 */
		bottom_jp = new JPanel();

		/*hour_filter = new JTextField("00:00", 5);
		bottom_jp.add(hour_filter);
		
		hour_end_filter = new JTextField("23:59", 5);
		bottom_jp.add(hour_end_filter);

		day_filter = new JTextField("", 2);
		bottom_jp.add(day_filter);

		month_filter = new JTextField("", 2);
		bottom_jp.add(month_filter);

		year_filter = new JTextField("", 4);
		bottom_jp.add(year_filter);
		
		Date today = new Date();
		SimpleDateFormat day = new SimpleDateFormat("dd");
		SimpleDateFormat month = new SimpleDateFormat("MM");
		SimpleDateFormat year = new SimpleDateFormat("yyyy");
		
		day_filter.setText(day.format(today));
		month_filter.setText(month.format(today));
		year_filter.setText(year.format(today));

		filter_jb = new JButton("Rechercher");
		filter_jb.addActionListener(this);
		bottom_jp.add(filter_jb);*/

		read_jb = new JButton("Lire la vidéo");
		read_jb.addActionListener(this);
		bottom_jp.add(read_jb);

		add(bottom_jp, BorderLayout.SOUTH);
	}

	@Override
	public void updateTableInfo() {
		setLocked(true);
		video_atm.setDataVector(populateModel(), COLUMN_NAMES);
		setLocked(false);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Object[][] populateModel() {
		if(applet.isUserLogged()) {

			Session session = applet.getSession();

			camera = this.camera_jp.getNodePanel().getCurrentCamera();
			
			ConfParser conf = new ConfParser();
			try {
				conf.parse(new File(AppletConstant.HIST_CONF_FILE));
			} catch (IOException e) {
				e.printStackTrace();
			}

			List<Video> resultats = new ArrayList<Video>();
			ArrayList<String> vid_path = new ArrayList<String>();
			String[] carac;
			
			for(Entry<String, String> e : conf.getChamps().entrySet()) {
				String videoName = ((String)e.getKey());
				carac = videoName.split("_");
				String realVideoName = "";
				
				for(int i = 0; i < carac.length; i++){
					if(i != (carac.length-1)){
						realVideoName += carac[i];
						if(i != (carac.length-2))	 realVideoName += "_";
					}
				}
				realVideoName += ".mp4.encrypt";
				
				//System.out.println("DebugHisto:"+realVideoName);
				if(carac[0].split("-")[1].equals(this.camera.getCam_ip())){
					List<Video> vid = session.createCriteria(Video.class).add(Restrictions.eq("video_name", realVideoName)).list();
					if(vid.size() > 0) {
						resultats.add(vid.get(0));
						vid_path.add((String) e.getValue());
					}
				}
			}
			
			if(resultats.size() != 0) {
				column_content = new Object[resultats.size()][COLUMN_NAMES.length];

				for(int i = 0; i < resultats.size(); i++) {
					column_content[i][0] = resultats.get(i);
					column_content[i][1] = resultats.get(i).getCamera();
					column_content[i][2] = resultats.get(i).getVideo_timeBegin();
					column_content[i][3] = resultats.get(i).getVideo_day();
					column_content[i][4] = resultats.get(i).getVideo_month();
					column_content[i][5] = resultats.get(i).getVideo_year();
					column_content[i][6] = FileUtils.readableFileSize(resultats.get(i).getVideo_weight());
				}
			}
			else {
				column_content = new Object[1][COLUMN_NAMES.length];
				for(int i=0; i<COLUMN_NAMES.length; i++)
					column_content[0][i] = "";
			}
			session.close();
			
			return column_content;
		}
		else
			return null;
	}

	public Camera getCamera() { return this.camera; }

	public Object[][] getColumnContent() { return this.column_content; }

	@Override
	public void actionPerformed(ActionEvent e) {
		/*if(e.getSource().equals(filter_jb)) {
			updateTableInfo();
		}*/
		if(e.getSource().equals(read_jb)) {
			ConfParser parser = new ConfParser();
			try {
				parser.parse(new File(AppletConstant.CLIENT_CONF_FILE));
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			
			String video_rep = parser.getValue("DOWNLOADED_VIDEO_PATH");
			
			if(video_jt.getSelectedRows().length > 0) {
				String requested_videos = "";
				for(int i : video_jt.getSelectedRows())
					requested_videos += String.valueOf(video_jt.getValueAt(i, 0))+":";
				requested_videos = requested_videos.substring(0, requested_videos.length()-1);
				
				// demande de keystore
				Session session = HibernateUtil.getSession();
				
				// liste des ips
				List<?> list = session.createCriteria(ServerCentral.class).list();
				ip_central = ((ServerCentral) list.get(0)).getServCentr_ip();

				list = session.createCriteria(ServerAuth.class).list();
				ip_auth = ((ServerAuth) list.get(0)).getAuth_ip_adress();

				list = session.createCriteria(ServerWeb.class).list();
				ip_web = ((ServerWeb) list.get(0)).getWebserv_ip();
				
				String user_name = (((User) session.createCriteria(User.class).
						add(Restrictions.like("user_id", this.applet.getUser_ID())).list().get(0))).getUser_name();
				
				ip_storage = ((Video) video_jt.getValueAt(video_jt.getSelectedRow(), 0)).getStorage().getStorserv_ip();
				
				ArrayList<String> msg_list = new ArrayList<String>();
				msg_list.add(KrakenClientMsg.KRAKEN_CLIENT.makeCommand());
				msg_list.add(KrakenClientMsg.ASK_FOR_TOKEN.makeCommand(
						" "+ip_central
						+ "  "+ip_auth
						+ "  "+REQUEST_TYPE_KEY
						+ "  "+user_name+":"+requested_videos
						+ "  "+ip_storage
						+ "  "+ip_cam));
				msg_list.add(KrakenClientMsg.END_CLIENT.makeCommand());

				KrakenClient key_client = new KrakenClient(msg_list, ip_web);
				key_client.connect();
				key_client.communicate();

				String answer_key = key_client.getFinalAnswer();
				
				if(answer_key.equalsIgnoreCase(KrakenServerMsg.END_SERVER.toString())) {
					String jeton_key = StringUtils.bytesToString(key_client.getSaved_data());

					ArrayList<String> msg_list_cmd = new ArrayList<>();
					msg_list_cmd.add(KrakenClientMsg.KRAKEN_SSL_CLIENT.makeCommand());
					msg_list_cmd.add(KrakenClientMsg.SEND_TOKEN_FOR_DOWNLOAD.makeCommand(" "+jeton_key));
					msg_list_cmd.add(KrakenClientMsg.READY_FOR_DOWNLOAD.makeCommand(" "+video_rep));
					msg_list_cmd.add(KrakenClientMsg.END_SSL_CLIENT.makeCommand());

					cmd_client = new KrakenSSLClient(msg_list_cmd, ip_storage, 0);
					cmd_client.setVCL_jp(camera_jp.getVlc_jp());

					NetworkThread cmd_network_thead = new NetworkThread(cmd_client);
					cmd_thread = new Thread(cmd_network_thead);
					cmd_thread.start();
					
					camera_jp.setPanel("Lecteur");
					camera_jp.getNodePanel().getTree().setSelectionRow(camera_jp.getNodePanel().getTree().getSelectionRows()[0]+1);
				}
			}
		}
	}

	@Override
	public void tableChanged(TableModelEvent e) {}

	// setters

	public void setIp_central(String ip_central) { this.ip_central = ip_central; }
	public void setIp_auth(String ip_auth) { this.ip_auth = ip_auth; }
	public void setIp_cam(String ip_cam) { this.ip_cam = ip_cam; }

}
